<template>
  <div class="root" ref="rootRef"></div>
  <div class="graph"></div>
  <div class="graph-io">
    <span title="下载 XML" @mousedown="downloadXml">
      <img
        src=""
        alt="下载XML" />
    </span>
    <span id="upload-xml" title="上传 XML">
      <input type="file" class="upload" @change="uploadXml" />
      <img class="upload-img"
        src=""
        alt="上传XML" />
    </span>
  </div>

  <el-drawer v-model="dialogVisible" direction="rtl" size="500px" :before-close="closeDialog" title="设置节点属性">
    <PropertyDialog v-if="dialogVisible" :nodeData="clickNode" :aa='123' :lf="lfRef" @setPropertiesFinish="closeDialog">
    </PropertyDialog>
  </el-drawer>
</template>

<script setup>
import { ref, onMounted, reactive } from "vue";
import LogicFlow from "@logicflow/core";
import {
  BpmnElement,
  BpmnXmlAdapter,
  Control,
  Menu,
  SelectionSelect,
  DndPanel,
} from "@logicflow/extension";
import "@logicflow/core/es/index.css";
import "@logicflow/extension/lib/style/index.css";
import {
  logicFlowJsonToFlowXml,
  skipText,
  snakerXml2LogicFlowJson,
} from "@/tools/tool.js";

// 注册
import Start from "@/components/WarmFlow/start";
import Between from "@/components/WarmFlow/between";
import Serial from "@/components/WarmFlow/serial";
import Parallel from "@/components/WarmFlow/parallel";
import End from "@/components/WarmFlow/end";
import Skip from "@/components/WarmFlow/skip";

//子组件
import { ElDrawer } from "element-plus";
import PropertyDialog from "@/components/PropertySetting/PropertyDialog.vue"

const rootRef = ref(null);
const lfRef = ref(null);
const value = reactive({});

// drawer
const dialogVisible = ref(false);
const clickNode = ref(null);

const download = (filename, text) => {
  const element = document.createElement("a");
  element.setAttribute(
    "href",
    "data:text/plain;charset=utf-8," + encodeURIComponent(text)
  );
  element.setAttribute("download", filename);
  element.style.display = "none";
  document.body.appendChild(element);
  element.click();
  document.body.removeChild(element);
};

const downloadXml = () => {
  const data = lfRef.value.getGraphData();
  download("logic-flow.xml", data);
};

const uploadXml = (ev) => {
  const file = ev.target.files[0];
  const reader = new FileReader();
  reader.onload = (event) => {
    if (event.target) {
      const xml = event.target.result;
      lfRef.value.render(xml);
    }
  };
  reader.readAsText(file);
};

const register = () => {
  lfRef.value.register(Start);
  lfRef.value.register(Between);
  lfRef.value.register(Serial);
  lfRef.value.register(Parallel);
  lfRef.value.register(End);
  lfRef.value.register(Skip);
};

const initControl = () => {
  // 控制面板-清空画布
  lfRef.value.extension.control.addItem({
    iconClass: "lf-control-clear",
    title: "clear",
    text: "清空",
    onClick: (lf, ev) => {
      lf.clearData();
    },
  });

  lfRef.value.extension.control.addItem({
    iconClass: "lf-control-save",
    title: "",
    text: "保存",
    onClick: (lf, ev) => {
      const graphData = lf.getGraphData();
      console.log("graphData:", graphData);
      value["nodes"] = graphData["nodes"];
      value["edges"] = graphData["edges"];
      console.log("this.value:", value);
      let xmlString = logicFlowJsonToFlowXml(value);
      console.log("this.xmlString:", xmlString);
      let data = {
        xmlString: xmlString,
        id: 123,
      };
      saveXml(data).then((response) => {
        alert("保存成功");
        if (response.code === 200) {
          // this.close();
        }
      });
    },
  });
};

const initMenu = () => {
  // 为菜单追加选项（必须在 lf.render() 之前设置）
  lfRef.value.extension.menu.addMenuConfig({
    nodeMenu: [
      {
        text: "属性",
        callback(node) {
          alert(`
          节点id：${node.id}
          节点类型：${node.type}
          节点坐标：(x: ${node.x}, y: ${node.y})
          文本坐标：(x: ${node.text.x}, y: ${node.text.y})`);
        },
      },
    ],
    edgeMenu: [
      {
        text: "属性",
        callback(edge) {
          alert(`
          边id：${edge.id}
          边类型：${edge.type}
          边坐标：(x: ${edge.x}, y: ${edge.y})
          文本坐标：(x: ${edge.text.x}, y: ${edge.text.y})
          源节点id：${edge.sourceNodeId}
          目标节点id：${edge.targetNodeId}`);
        },
      },
    ],
  });
};

const initEvent = () => {
  const { eventCenter } = lfRef.value.graphModel;
  eventCenter.on("node:click", (args) => {
    console.log("node:click data：", args);
    let nodeClick = args.data;
    console.log("node:click");
    console.log(nodeClick);

    clickNode.value = args
    dialogVisible.value = true
    // this.$nextTick(() => {
    //   this.$refs.propertySetting.show()
    // })
  });

  eventCenter.on("edge:click", (args) => {
    console.log("edge:click");
    console.log(args);
    let nodeClick = args.data;
    const nodeModel = lfRef.value.getNodeModelById(nodeClick.sourceNodeId);
    const skipConditionShow = nodeModel.type === "serial";
    // this.$nextTick(() => {
    //   this.$refs.propertySetting.show(nodeModel.nodeType === 'serial')
    // })
  });

  eventCenter.on("edge:add", (args) => {
    lfRef.value.changeEdgeType(args.data.id, "skip");
    // 修改边类型
    lfRef.value.setProperties(args.data.id, {
      skipType: "PASS",
    });
  });

  eventCenter.on("blank:click", (args) => {
    let nodeClick = null;
    // this.$nextTick(() => {
    //   this.$refs.propertySetting.handleClose()
    // })
  });
};

onMounted(() => {
  lfRef.value = new LogicFlow({
    container: rootRef.value,
    stopZoomGraph: true, // 禁止缩放画布
    metaKeyMultipleSelected: true,
    grid: {
      size: 20,
      visible: true,
      type: "dot",
      config: {
        color: "#ababab",
        thickness: 1,
      },
    },
    keyboard: {
      enabled: true,
    },
    snapline: true, // 是否启用节点辅助对齐线。
    plugins: [
      BpmnElement,
      BpmnXmlAdapter,
      Control,
      Menu,
      SelectionSelect,
      DndPanel,
    ],
  });

  lfRef.value.setTheme({
    snapline: {
      stroke: "#999", // 对齐线颜色
      strokeWidth: 3, // 对齐线宽度
    },
  });

  initControl();

  initMenu();

  initEvent();

  register();

  lfRef.value.setPatternItems([
    {
      type: "start",
      text: "开始",
      label: "开始节点",
      icon: "",
    },
    {
      type: "between",
      text: "中间节点",
      label: "中间节点",
      icon: "",
      className: "important-node",
      properties: {},
    },
    {
      type: "serial",
      text: "",
      label: "互斥网关",
      properties: {},
      icon: "",
    },
    {
      type: "parallel",
      text: "",
      label: "并行网关",
      properties: {},
      icon: "",
    },
    {
      type: "end",
      text: "结束",
      label: "结束节点",
      icon: "",
    },
  ]);

  lfRef.value.render({});

  // http://www.hhzai.top/flow/flow-design/index/1272591609623613440?disabled=true&pageNum=1
  // https://site.logic-flow.cn/
});

const closeDialog = () => {
  dialogVisible.value = false;
}
</script>

<style>
.root {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.explain {
  height: 30px;
}

.graph {
  width: 100%;
  height: calc(100% - 30px);
}

.graph-io {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 9999;
  background: rgba(255, 255, 255, 0.8);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  padding: 10px;
  display: flex;
}

.graph-io>span {
  margin: 0 5px;
  cursor: pointer;
}

#upload-xml {
  position: relative;
  overflow: hidden;
  display: inline-block;
  cursor: pointer;
}

.upload {
  position: absolute;
  z-index: 99;
  left: 0;
  top: 0;
  opacity: 0;
  cursor: pointer;
}

.upload::-webkit-file-upload-button {
  cursor: pointer;
}

.upload-img {
  width: 26px;
}
</style>

<style>
.lf-control-save {
  background-image: url("");
}

.lf-control-clear {
  background-image: url("");
}
</style>
